#! /bin/sh -e

# All lines beginning with `# DP:' are a description of the patch.
# DP: Add grsecurity enhancements to glibc
# DP: * Adds Stefan Esser's unlink sanity check
# DP: * Removes LD_DEBUG for suid apps
# DP: * Fixes a glibc bug where certain envvars are interpreted
# DP:   even if UNSECURE_ENVVARS says to drop them

if [ $# -ne 2 ]; then
    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
    exit 1
fi
case "$1" in
    -patch) patch -d "$2" -f --no-backup-if-mismatch -p0 < $0;;
    -unpatch) patch -d "$2" -f --no-backup-if-mismatch -R -p0 < $0;;
    *)
        echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
        exit 1
esac
exit 0

--- malloc/malloc.c	2004-08-03 18:06:35 -0400
+++ malloc/malloc.c	2004-08-03 18:08:53 -0400
@@ -311,6 +311,10 @@
 #define assert(x) ((void)0)
 #endif
 
+#include <abort-instr.h>
+#ifndef ABORT_INSTRUCTION
+#define ABORT_INSTRUCTION
+#endif
 
 /*
   INTERNAL_SIZE_T is the word-size used for internal bookkeeping
@@ -1951,6 +1955,13 @@
 #define unlink(P, BK, FD) {                                            \
   FD = P->fd;                                                          \
   BK = P->bk;                                                          \
+  if (FD->bk != P || BK->fd != P)                                      \
+  {                                                                    \
+    ABORT_INSTRUCTION;                                                 \
+    _exit(127);                                                        \
+    while (1)                                                          \
+      ABORT_INSTRUCTION;                                               \
+  }                                                                    \
   FD->bk = BK;                                                         \
   BK->fd = FD;                                                         \
 }
--- sysdeps/generic/unsecvars.h	2004-08-03 18:13:13 -0400
+++ sysdeps/generic/unsecvars.h	2004-08-03 18:11:41 -0400
@@ -3,6 +3,8 @@
    with a '\0' explicitly.  */
 #define UNSECURE_ENVVARS \
   "LD_PRELOAD\0"							      \
+  "LD_DEBUG\0"								      \
+  "LD_TRACE_PRELINKING\0"							      \
   "LD_LIBRARY_PATH\0"							      \
   "LD_ORIGIN_PATH\0"							      \
   "LD_DEBUG_OUTPUT\0"							      \
--- elf/rtld.c	2003-01-07 13:47:35 -0500
+++ elf/rtld.c	2004-08-03 22:15:51 -0400
@@ -1762,6 +1762,30 @@
   GL(dl_profile_output)
     = &"/var/tmp\0/var/profile"[INTUSE(__libc_enable_secure) ? 9 : 0];
 
+  /* Extra security for SUID binaries.  Remove all dangerous environment
+     variables.  */
+  if (__builtin_expect (INTUSE(__libc_enable_secure), 0))
+    {
+      static const char unsecure_envvars[] =
+#ifdef EXTRA_UNSECURE_ENVVARS
+	EXTRA_UNSECURE_ENVVARS
+#endif
+	UNSECURE_ENVVARS;
+      const char *nextp;
+
+      nextp = unsecure_envvars;
+      do
+	{
+	  unsetenv (nextp);
+	  /* We could use rawmemchr but this need not be fast.  */
+	  nextp = (char *) (strchr) (nextp, '\0') + 1;
+	}
+      while (*nextp != '\0');
+
+      if (__access ("/etc/suid-debug", F_OK) != 0)
+	unsetenv ("MALLOC_CHECK_");
+    }
+
   while ((envline = _dl_next_ld_env_entry (&runp)) != NULL)
     {
       size_t len = 0;
@@ -1897,33 +1921,10 @@
   /* The caller wants this information.  */
   *modep = mode;
 
-  /* Extra security for SUID binaries.  Remove all dangerous environment
-     variables.  */
-  if (__builtin_expect (INTUSE(__libc_enable_secure), 0))
-    {
-      static const char unsecure_envvars[] =
-#ifdef EXTRA_UNSECURE_ENVVARS
-	EXTRA_UNSECURE_ENVVARS
-#endif
-	UNSECURE_ENVVARS;
-      const char *nextp;
-
-      nextp = unsecure_envvars;
-      do
-	{
-	  unsetenv (nextp);
-	  /* We could use rawmemchr but this need not be fast.  */
-	  nextp = (char *) (strchr) (nextp, '\0') + 1;
-	}
-      while (*nextp != '\0');
-
-      if (__access ("/etc/suid-debug", F_OK) != 0)
-	unsetenv ("MALLOC_CHECK_");
-    }
   /* If we have to run the dynamic linker in debugging mode and the
      LD_DEBUG_OUTPUT environment variable is given, we write the debug
      messages to this file.  */
-  else if (any_debug && debug_output != NULL)
+  if (any_debug && debug_output != NULL)
     {
 #ifdef O_NOFOLLOW
       const int flags = O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW;
